import os
import random
import string
from PIL import Image, ImageFont, ImageDraw, ImageFilter


class ImageVerify:
    # 属性的初始化 图片验证码的属性有那些
    def __init__(self, x=140, y=40, length=4, size=28):
        """
        初始化方法
        :param x:图片的宽度
        :param x:图片的高度
        :param x:字符个数 答案的文字个数
        :param x:字体大小
        """
        self.x = x
        self.y = y
        self.length = length
        self.size = size

    # 随机生成图片里面的文字
    def random_str(self):
        # 答案的组成为数字加字母
        source = string.ascii_letters + string.digits
        # 随机从资源中挑选的四个字符，不重复挑选
        return ''.join(random.sample(source, self.length))

    def random_color(self, start=0, end=255):
        # 颜色的值在0-255之间,需要生成三个基础色 红绿蓝 存在一个元祖里面
        res = [random.randint(start, end) for i in range(3)]
        # 返回数据是转为tuple类型
        return tuple(res)

    # 生成干扰线 draw画笔对象
    def random_lines(self, draw):
        for i in range(self.length):
            lines = [(random.randint(0, self.x), random.randint(0, self.y)) for i in range(2)]
            draw.line(lines, fill=self.random_color(64, 200))

    # 生成干扰点 rate是生成频率 决定了干扰点的密集性，大概是多还是少
    def random_points(self, draw, rate):
        for x in range(self.x):
            for y in range(self.y):
                if random.randint(1, 100) <= rate:
                    draw.point((x, y), fill=self.random_color(64, 200))

    # 拼接成一张图片
    def verify_code(self):
        # 通道  宽高  背景颜色 画布对象
        image = Image.new('RGB', (self.x, self.y), (255, 255, 255))

        # 创建字体
        # 获取当前脚本文件所在的文件夹的绝对路径 找到utils文件夹
        file = os.path.dirname(os.path.abspath(__file__))
        # 字体对象 类型 大小
        font = ImageFont.truetype(f'{file}/HYYakuHei-85W.ttf', self.size)
        # 创建Draw对象 画笔对象 在画布上创建画笔
        draw = ImageDraw.Draw(image)

        # 绘制干扰点
        self.random_points(draw, 15)
        # 绘制干扰线
        self.random_lines(draw)

        # 绘制答案
        code = self.random_str()
        for i in range(self.length):
            # 坐标轴 文字内容code[i]下标取值 字体 颜色
            draw.text((i * 35, random.randint(3, 6)), code[i], font=font, fill=self.random_color(32, 127))

        # 高斯模糊滤镜
        image = image.filter(ImageFilter.BLUR)

        return image, code


# 判断运行的程序是不是当前这个文件在运行
# 结果为真则代表是当前的文件在运行以下程序
# 文件成为一个模块
if __name__ == "__main__":
    # 生成一个实例对象
    imageverify = ImageVerify()
    img, code = imageverify.verify_code()
    # 把数据保存成图片文件
    with open('code.jpg', 'wb') as fp:
        img.save(fp)

    print(code)
    # print(imageverify.random_str())
    # print("=" * 20)
    # print(imageverify.random_color())
